UNPKG

@lobehub/chat

Version:

Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.

132 lines (118 loc) 3.88 kB
import { Generation, GenerationBatch } from '@/types/generation'; // Default maximum width for image items export const DEFAULT_MAX_ITEM_WIDTH = 200; /** * Get image dimensions from various sources * Returns width, height and aspect ratio when available */ export const getImageDimensions = ( generation: Generation, generationBatch?: GenerationBatch, ): { aspectRatio: string | null; height: number | null; width: number | null } => { // 1. Priority: actual dimensions from asset if ( generation.asset?.width && generation.asset?.height && generation.asset.width > 0 && generation.asset.height > 0 ) { const { width, height } = generation.asset; return { aspectRatio: `${width} / ${height}`, height, width, }; } // 2. Try to get dimensions from generationBatch config const config = generationBatch?.config; if (config?.width && config?.height && config.width > 0 && config.height > 0) { const { width, height } = config; return { aspectRatio: `${width} / ${height}`, height, width, }; } // 3. Try to get dimensions from generationBatch top-level if ( generationBatch?.width && generationBatch?.height && generationBatch.width > 0 && generationBatch.height > 0 ) { const { width, height } = generationBatch; return { aspectRatio: `${width} / ${height}`, height, width, }; } // 4. Try to parse from size parameter (format: "1024x768") if (config?.size && config.size !== 'auto') { const sizeMatch = config.size.match(/^(\d+)x(\d+)$/); if (sizeMatch) { const [, widthStr, heightStr] = sizeMatch; const width = parseInt(widthStr, 10); const height = parseInt(heightStr, 10); if (width > 0 && height > 0) { return { aspectRatio: `${width} / ${height}`, height, width, }; } } } // 5. Try to get aspect ratio only (format: "16:9") if (config?.aspectRatio) { const ratioMatch = config.aspectRatio.match(/^(\d+):(\d+)$/); if (ratioMatch) { const [, x, y] = ratioMatch; return { aspectRatio: `${x} / ${y}`, height: null, width: null, }; } } // 6. No dimensions available return { aspectRatio: null, height: null, width: null, }; }; export const getAspectRatio = ( generation: Generation, generationBatch?: GenerationBatch, ): string => { const dimensions = getImageDimensions(generation, generationBatch); return dimensions.aspectRatio || '1 / 1'; }; /** * Calculate display max width for generation items * Ensures height doesn't exceed half screen height based on original aspect ratio * * @note This function is only used in client-side rendering environments. * It directly accesses window.innerHeight and is not designed for SSR compatibility. */ export const getThumbnailMaxWidth = ( generation: Generation, generationBatch?: GenerationBatch, ): number => { const dimensions = getImageDimensions(generation, generationBatch); // Return default width if no dimension information is available if (!dimensions.aspectRatio) { return DEFAULT_MAX_ITEM_WIDTH; } // Parse aspect ratio string (format: "16 / 9") const [widthStr, heightStr] = dimensions.aspectRatio.split(' / '); const aspectRatio = Number(widthStr) / Number(heightStr); // Apply screen height constraint (half of screen height) // Note: window.innerHeight is safe to use here as this function is client-side only const maxScreenHeight = window.innerHeight / 2; const maxWidthFromHeight = Math.round(maxScreenHeight * aspectRatio); // Use the smaller of: calculated width from height constraint or a reasonable maximum const maxReasonableWidth = DEFAULT_MAX_ITEM_WIDTH * 2; return Math.min(maxWidthFromHeight, maxReasonableWidth); };